using DA.AnimGraph;
using System;
using System.Net.NetworkInformation;
using System.Security.Cryptography;


namespace DA.AnimGraph.Editor {
    public static class AUIDGenerator {
        private const int sequenceMask = 0b00001111;
        private const long timestampMask = 0xfffffffff;


        private static readonly DateTime Epoch = new DateTime(2020, 10, 15, 0, 0, 0, DateTimeKind.Utc);
        //private static readonly Random Random = new Random();
        private static readonly long MAC = GetMAC();

        private static long lastTimestamp;
        private static int sequence;

        private static long GetMAC() {
            // 获取机器的MAC地址
            foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) {
                var address = nic.GetPhysicalAddress();
                if (address != null && address.ToString().Length == 12) {
                    return BytesToLong(address.GetAddressBytes());
                }
            }

            // 如果获取不到MAC地址，则生成随机的节点ID
            var randomNode = new byte[3];
            RandomNumberGenerator.Fill(randomNode);
            return BytesToLong(randomNode);
        }

        private static long BytesToLong(byte[] bytes) {
            byte b1 = bytes.Length >= 1 ? bytes[^1] : (byte)0;
            byte b2 = bytes.Length >= 2 ? bytes[^2] : (byte)0;
            byte b3 = bytes.Length >= 3 ? bytes[^3] : (byte)0;

            long r = b3;
            r = r << 8;
            r |= b2;
            r = r << 8;
            r |= b1;

            r = r << (64 - 24);
            return r;
        }

        // MAC地址低24位 + 时间戳低36位 + 计数4位
        public static AUID Gen() {
            long auid = MAC;
            var timestamp = GetTimestamp() & timestampMask;
            timestamp = timestamp << 4;
            auid |= timestamp;
            auid |= (long)sequence;
            return new AUID(auid);
        }

        private static long GetTimestamp() {
            long timestamp = (DateTime.UtcNow - Epoch).Ticks;
            while (true) {
                if (timestamp != lastTimestamp) {
                    lastTimestamp = timestamp;
                    sequence = 0;
                    return timestamp;
                } else {
                    sequence = (sequence + 1) & sequenceMask;
                    if (sequence == 0) {
                        timestamp = TillNextMillis();
                    } else {
                        return timestamp;
                    }
                }
            }
        }

        //阻塞到下一个毫秒，直到获得新的时间戳
        private static long TillNextMillis() {
            long timestamp = (DateTime.UtcNow - Epoch).Ticks;
            while (timestamp <= lastTimestamp) {
                timestamp = (DateTime.UtcNow - Epoch).Ticks;
            }
            return timestamp;
        }
    }
}


//public class UUIDv1Generator {
//    private static readonly DateTime Epoch = new DateTime(1582, 10, 15, 0, 0, 0, DateTimeKind.Utc);
//    private static readonly Random Random = new Random();
//    private static readonly byte[] Node = GetNode();

//    public static Guid GenerateUUIDv1() {
//        var timestamp = (DateTime.UtcNow - Epoch).Ticks;

//        var timeLow = (uint)(timestamp & 0xFFFFFFFF);
//        var timeMid = (ushort)((timestamp >> 32) & 0xFFFF);
//        var timeHiAndVersion = (ushort)(((timestamp >> 48) & 0x0FFF) | (1 << 12)); // Version 1

//        var clockSeq = (ushort)Random.Next(0, 1 << 14);
//        var clockSeqHiAndRes = (byte)((clockSeq >> 8) | 0x80); // Variant is 10x

//        var guidBytes = new byte[16];
//        Array.Copy(BitConverter.GetBytes(timeLow), 0, guidBytes, 0, 4);
//        Array.Copy(BitConverter.GetBytes(timeMid), 0, guidBytes, 4, 2);
//        Array.Copy(BitConverter.GetBytes(timeHiAndVersion), 0, guidBytes, 6, 2);
//        guidBytes[8] = clockSeqHiAndRes;
//        guidBytes[9] = (byte)clockSeq;
//        Array.Copy(Node, 0, guidBytes, 10, 6);

//        return new Guid(guidBytes);
//    }

//    private static byte[] GetNode() {
//        // 获取机器的MAC地址
//        foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) {
//            var address = nic.GetPhysicalAddress();
//            if (address != null && address.ToString().Length == 12) {
//                return address.GetAddressBytes();
//            }
//        }

//        // 如果获取不到MAC地址，则生成随机的节点ID
//        var randomNode = new byte[6];
//        RandomNumberGenerator.Fill(randomNode);
//        randomNode[0] |= 0x01;
//        return randomNode;
//    }
//}
